//! # 服务发现管理模块
//!
//! 提供针对管理后台的服务发现功能，复用 rustcloud-registry 的核心接口

use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;

use rustcloud_core::{ServiceInstance, ServiceRegistry};
use crate::{AdminResult, AdminError};

/// 服务发现管理器
/// 
/// 这是一个管理层的 struct，它聚合了底层的 ServiceRegistry trait
/// 为管理后台提供额外的管理功能，而不是重新实现服务发现
pub struct ServiceDiscoveryManager {
    /// 底层服务注册中心（复用 rustcloud-registry）
    registry: Arc<dyn ServiceRegistry>,
    /// 管理配置
    config: DiscoveryManagerConfig,
    /// 缓存的服务信息
    service_cache: Arc<tokio::sync::RwLock<HashMap<String, CachedServiceInfo>>>,
    /// 统计信息
    stats: Arc<tokio::sync::RwLock<DiscoveryManagerStats>>,
}

/// 发现管理器配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DiscoveryManagerConfig {
    /// 缓存过期时间
    pub cache_ttl: Duration,
    /// 健康检查间隔
    pub health_check_interval: Duration,
    /// 监控间隔
    pub monitoring_interval: Duration,
    /// 是否启用自动清理
    pub auto_cleanup: bool,
}

impl Default for DiscoveryManagerConfig {
    fn default() -> Self {
        Self {
            cache_ttl: Duration::from_secs(300),
            health_check_interval: Duration::from_secs(30),
            monitoring_interval: Duration::from_secs(60),
            auto_cleanup: true,
        }
    }
}

/// 缓存的服务信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CachedServiceInfo {
    /// 服务名称
    pub service_name: String,
    /// 实例列表
    pub instances: Vec<ServiceInstance>,
    /// 健康实例数量
    pub healthy_count: usize,
    /// 总实例数量
    pub total_count: usize,
    /// 最后更新时间
    pub last_updated: chrono::DateTime<chrono::Utc>,
    /// 缓存过期时间
    pub expires_at: chrono::DateTime<chrono::Utc>,
}

/// 发现管理器统计信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DiscoveryManagerStats {
    /// 管理的服务数量
    pub managed_services_count: usize,
    /// 总实例数量
    pub total_instances_count: usize,
    /// 健康实例数量
    pub healthy_instances_count: usize,
    /// 缓存命中次数
    pub cache_hits: u64,
    /// 缓存未命中次数
    pub cache_misses: u64,
    /// 健康检查次数
    pub health_checks_performed: u64,
    /// 最后统计更新时间
    pub last_updated: chrono::DateTime<chrono::Utc>,
}

impl Default for DiscoveryManagerStats {
    fn default() -> Self {
        Self {
            managed_services_count: 0,
            total_instances_count: 0,
            healthy_instances_count: 0,
            cache_hits: 0,
            cache_misses: 0,
            health_checks_performed: 0,
            last_updated: chrono::Utc::now(),
        }
    }
}

/// 服务健康状态报告
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServiceHealthReport {
    /// 服务名称
    pub service_name: String,
    /// 健康实例列表
    pub healthy_instances: Vec<ServiceInstance>,
    /// 不健康实例列表
    pub unhealthy_instances: Vec<ServiceInstance>,
    /// 健康率
    pub health_ratio: f64,
    /// 检查时间
    pub check_time: chrono::DateTime<chrono::Utc>,
}

/// 服务拓扑信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServiceTopology {
    /// 所有服务的映射
    pub services: HashMap<String, ServiceTopologyNode>,
    /// 总服务数量
    pub total_services: usize,
    /// 总实例数量
    pub total_instances: usize,
}

/// 服务拓扑节点
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServiceTopologyNode {
    /// 服务名称
    pub name: String,
    /// 实例数量
    pub instance_count: usize,
    /// 健康实例数量
    pub healthy_count: usize,
    /// 服务标签
    pub tags: HashMap<String, String>,
    /// 依赖的服务
    pub dependencies: Vec<String>,
}

impl ServiceDiscoveryManager {
    /// 创建新的服务发现管理器
    pub fn new(
        registry: Arc<dyn ServiceRegistry>,
        config: DiscoveryManagerConfig,
    ) -> Self {
        Self {
            registry,
            config,
            service_cache: Arc::new(tokio::sync::RwLock::new(HashMap::new())),
            stats: Arc::new(tokio::sync::RwLock::new(DiscoveryManagerStats::default())),
        }
    }

    /// 使用默认配置创建管理器
    pub fn with_defaults(registry: Arc<dyn ServiceRegistry>) -> Self {
        Self::new(registry, DiscoveryManagerConfig::default())
    }

    /// 获取所有服务的概览信息
    pub async fn get_services_overview(&self) -> AdminResult<Vec<ServiceOverview>> {
        // 先尝试从注册中心获取服务列表
        let service_names = self.registry.list_services().await
            .map_err(|e| AdminError::system_info_error(&format!("获取服务列表失败: {}", e)))?;

        let mut overviews = Vec::new();
        
        for service_name in service_names {
            if let Ok(overview) = self.get_service_overview(&service_name).await {
                overviews.push(overview);
            }
        }

        Ok(overviews)
    }

    /// 获取单个服务的概览信息
    pub async fn get_service_overview(&self, service_name: &str) -> AdminResult<ServiceOverview> {
        // 首先检查缓存
        if let Some(cached_info) = self.get_from_cache(service_name).await {
            let mut stats = self.stats.write().await;
            stats.cache_hits += 1;
            
            return Ok(ServiceOverview {
                name: service_name.to_string(),
                total_instances: cached_info.total_count,
                healthy_instances: cached_info.healthy_count,
                last_updated: cached_info.last_updated,
                status: if cached_info.healthy_count > 0 { 
                    ServiceStatus::Healthy 
                } else { 
                    ServiceStatus::Unhealthy 
                },
            });
        }

        // 缓存未命中，从注册中心获取
        let mut stats = self.stats.write().await;
        stats.cache_misses += 1;
        drop(stats);

        let instances = self.registry.discover(service_name).await
            .map_err(|e| AdminError::system_info_error(&format!("发现服务失败: {}", e)))?;

        let healthy_instances: Vec<_> = instances.iter().filter(|i| i.healthy).cloned().collect();
        let healthy_count = healthy_instances.len();
        let total_count = instances.len();

        // 更新缓存
        self.update_cache(service_name, instances.clone()).await?;

        Ok(ServiceOverview {
            name: service_name.to_string(),
            total_instances: total_count,
            healthy_instances: healthy_count,
            last_updated: chrono::Utc::now(),
            status: if healthy_count > 0 { 
                ServiceStatus::Healthy 
            } else { 
                ServiceStatus::Unhealthy 
            },
        })
    }

    /// 获取服务的详细实例信息
    pub async fn get_service_instances(&self, service_name: &str) -> AdminResult<Vec<ServiceInstanceDetail>> {
        let instances = self.registry.discover(service_name).await
            .map_err(|e| AdminError::system_info_error(&format!("获取服务实例失败: {}", e)))?;

        let mut details = Vec::new();
        
        for instance in instances {
            // 执行健康检查（如果支持）
            let health_status = match self.registry.health_check(service_name).await {
                Ok(healthy_instances) => {
                    healthy_instances.iter().any(|hi| 
                        hi.host == instance.host && hi.port == instance.port
                    )
                }
                Err(_) => instance.healthy, // fallback to instance health
            };

            details.push(ServiceInstanceDetail {
                host: instance.host,
                port: instance.port,
                protocol: instance.protocol,
                healthy: health_status,
                metadata: instance.metadata,
                last_heartbeat: chrono::Utc::now(), // 实际应该从注册中心获取
                uptime_seconds: None, // 可以从元数据中解析
            });
        }

        Ok(details)
    }

    /// 执行服务健康检查
    pub async fn perform_health_check(&self, service_name: &str) -> AdminResult<ServiceHealthReport> {
        let instances = self.registry.discover(service_name).await
            .map_err(|e| AdminError::system_info_error(&format!("健康检查失败: {}", e)))?;

        let healthy_instances = self.registry.health_check(service_name).await
            .map_err(|e| AdminError::system_info_error(&format!("获取健康实例失败: {}", e)))?;

        let unhealthy_instances: Vec<_> = instances.into_iter()
            .filter(|instance| {
                !healthy_instances.iter().any(|hi| 
                    hi.host == instance.host && hi.port == instance.port
                )
            })
            .collect();

        let total_count = healthy_instances.len() + unhealthy_instances.len();
        let health_ratio = if total_count > 0 {
            healthy_instances.len() as f64 / total_count as f64
        } else {
            0.0
        };

        // 更新统计信息
        {
            let mut stats = self.stats.write().await;
            stats.health_checks_performed += 1;
        }

        Ok(ServiceHealthReport {
            service_name: service_name.to_string(),
            healthy_instances,
            unhealthy_instances,
            health_ratio,
            check_time: chrono::Utc::now(),
        })
    }

    /// 获取服务拓扑
    pub async fn get_service_topology(&self) -> AdminResult<ServiceTopology> {
        let service_names = self.registry.list_services().await
            .map_err(|e| AdminError::system_info_error(&format!("获取服务拓扑失败: {}", e)))?;

        let mut services = HashMap::new();
        let mut total_instances = 0;

        for service_name in &service_names {
            let instances = self.registry.discover(service_name).await
                .unwrap_or_default();

            let healthy_count = instances.iter().filter(|i| i.healthy).count();
            total_instances += instances.len();

            // 从实例元数据中提取标签
            let mut tags = HashMap::new();
            for instance in &instances {
                for (key, value) in &instance.metadata {
                    tags.insert(key.clone(), value.clone());
                }
            }

            services.insert(service_name.clone(), ServiceTopologyNode {
                name: service_name.clone(),
                instance_count: instances.len(),
                healthy_count,
                tags,
                dependencies: Vec::new(), // 实际应该从服务配置或元数据中获取
            });
        }

        Ok(ServiceTopology {
            services,
            total_services: service_names.len(),
            total_instances,
        })
    }

    /// 获取管理器统计信息
    pub async fn get_stats(&self) -> AdminResult<DiscoveryManagerStats> {
        Ok(self.stats.read().await.clone())
    }

    /// 强制刷新服务缓存
    pub async fn refresh_cache(&self, service_name: Option<&str>) -> AdminResult<()> {
        match service_name {
            Some(name) => {
                // 刷新特定服务的缓存
                let instances = self.registry.discover(name).await
                    .map_err(|e| AdminError::system_info_error(&format!("刷新缓存失败: {}", e)))?;
                self.update_cache(name, instances).await?;
            }
            None => {
                // 刷新所有服务的缓存
                let service_names = self.registry.list_services().await
                    .map_err(|e| AdminError::system_info_error(&format!("获取服务列表失败: {}", e)))?;
                
                for service_name in service_names {
                    if let Ok(instances) = self.registry.discover(&service_name).await {
                        let _ = self.update_cache(&service_name, instances).await;
                    }
                }
            }
        }
        Ok(())
    }

    /// 从缓存获取服务信息
    async fn get_from_cache(&self, service_name: &str) -> Option<CachedServiceInfo> {
        let cache = self.service_cache.read().await;
        let cached_info = cache.get(service_name)?;
        
        // 检查缓存是否过期
        if chrono::Utc::now() > cached_info.expires_at {
            return None;
        }
        
        Some(cached_info.clone())
    }

    /// 更新缓存
    async fn update_cache(&self, service_name: &str, instances: Vec<ServiceInstance>) -> AdminResult<()> {
        let healthy_count = instances.iter().filter(|i| i.healthy).count();
        let total_count = instances.len();
        let now = chrono::Utc::now();

        let cached_info = CachedServiceInfo {
            service_name: service_name.to_string(),
            instances,
            healthy_count,
            total_count,
            last_updated: now,
            expires_at: now + self.config.cache_ttl,
        };

        {
            let mut cache = self.service_cache.write().await;
            cache.insert(service_name.to_string(), cached_info);
        }

        Ok(())
    }
}

/// 服务概览信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServiceOverview {
    /// 服务名称
    pub name: String,
    /// 总实例数
    pub total_instances: usize,
    /// 健康实例数
    pub healthy_instances: usize,
    /// 最后更新时间
    pub last_updated: chrono::DateTime<chrono::Utc>,
    /// 服务状态
    pub status: ServiceStatus,
}

/// 服务状态
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum ServiceStatus {
    /// 健康
    Healthy,
    /// 不健康
    Unhealthy,
    /// 部分健康
    Degraded,
    /// 未知
    Unknown,
}

/// 服务实例详情
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServiceInstanceDetail {
    /// 主机地址
    pub host: String,
    /// 端口
    pub port: u16,
    /// 协议
    pub protocol: String,
    /// 是否健康
    pub healthy: bool,
    /// 元数据
    pub metadata: HashMap<String, String>,
    /// 最后心跳时间
    pub last_heartbeat: chrono::DateTime<chrono::Utc>,
    /// 运行时间（秒）
    pub uptime_seconds: Option<u64>,
}

#[cfg(test)]
mod tests {
    use super::*;
    use rustcloud_registry::InMemoryRegistry;
    use rustcloud_core::ServiceInstance;

    #[tokio::test]
    async fn test_service_discovery_manager() {
        let registry = Arc::new(InMemoryRegistry::new());
        let manager = ServiceDiscoveryManager::with_defaults(registry.clone());

        // 注册测试服务
        let instance = ServiceInstance::new("test-service", "localhost", 8080, "http");
        registry.register(instance).await.unwrap();

        // 测试获取服务概览
        let overview = manager.get_service_overview("test-service").await.unwrap();
        assert_eq!(overview.name, "test-service");
        assert_eq!(overview.total_instances, 1);
    }

    #[tokio::test]
    async fn test_service_health_check() {
        let registry = Arc::new(InMemoryRegistry::new());
        let manager = ServiceDiscoveryManager::with_defaults(registry.clone());

        // 注册测试服务
        let mut instance = ServiceInstance::new("test-service", "localhost", 8080, "http");
        instance.healthy = true;
        registry.register(instance).await.unwrap();

        // 执行健康检查
        let health_report = manager.perform_health_check("test-service").await.unwrap();
        assert_eq!(health_report.service_name, "test-service");
        assert_eq!(health_report.healthy_instances.len(), 1);
        assert_eq!(health_report.unhealthy_instances.len(), 0);
        assert_eq!(health_report.health_ratio, 1.0);
    }
}